package com.zh.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zh.common.exception.BusinessException;
import com.zh.system.domain.dto.ConfirmMessageDto;
import com.zh.system.domain.dto.PageMessageDto;
import com.zh.system.domain.entity.SysMsgFrom;
import com.zh.system.domain.entity.SysMsgTemplate;
import com.zh.system.domain.entity.SysMsgTo;
import com.zh.system.domain.vo.MessageVo;
import com.zh.system.mapper.SysMsgFromMapper;
import com.zh.system.mapper.SysMsgToMapper;
import com.zh.system.service.SysMessageService;
import com.zh.system.service.SysMessageTemplateService;
import com.zh.web.base.PageApiResult;
import com.zh.web.domain.system.dto.MessageDto;
import com.zh.web.enums.Deletion;
import com.zh.web.enums.Status;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class SysMessageServiceImpl implements SysMessageService {

    private final SysMsgFromMapper sysMsgFromMapper;
    private final SysMsgToMapper sysMsgToMapper;
    private final SysMessageTemplateService sysMessageTemplateService;

    @Override
    @Transactional
    public String sendMessage(MessageDto messageDto) {
        //参数校验
        Long fromId = Optional.of(messageDto.getFromId())
                .orElseThrow(() -> new BusinessException("发送者Id不能为空"));
        List<Long> toList = Optional.of(messageDto.getToIdList())
                .orElseThrow(() -> new BusinessException("接收者Id不能为空"));
        //存储消息
        SysMsgFrom sysMsgFrom = new SysMsgFrom();
        sysMsgFrom.setFromId(fromId);
        //消息体 是否启用了模板
        String content = this.standardContent(messageDto.getContent(), messageDto.getTemplateId());
        sysMsgFrom.setContent(content);
        sysMsgFrom.setType(messageDto.getType());
        sysMsgFrom.setCreateOperator(messageDto.getCreateOperator());
        sysMsgFrom.setUpdateOperator(messageDto.getUpdateOperator());
        sysMsgFromMapper.insert(sysMsgFrom);
        Long msgId = sysMsgFrom.getId();
        //接收消息
        List<SysMsgTo> msgToList = toList.stream().map(to -> {
            SysMsgTo sysMsgTo = new SysMsgTo();
            sysMsgTo.setMsgId(msgId);
            sysMsgTo.setToId(to);
            sysMsgTo.setCreateOperator(messageDto.getCreateOperator());
            sysMsgTo.setUpdateOperator(messageDto.getUpdateOperator());
            sysMsgTo.setCreateTime(sysMsgFrom.getCreateTime());
            sysMsgTo.setUpdateTime(sysMsgFrom.getUpdateTime());
            sysMsgTo.setStatus(Status.ENABLE);
            sysMsgTo.setDeleted(Deletion.NOT_DELETED);
            return sysMsgTo;
        }).collect(Collectors.toList());
        Integer count = sysMsgToMapper.insertBatch(msgToList);
        boolean success = msgId != null && count > 0;
        if (success) {
            return "发送成功";
        } else {
            throw new BusinessException("发送失败");
        }
    }

    @Transactional
    @Override
    public void confirmMessage(ConfirmMessageDto confirmMessageDto) {
        SysMsgTo sysMsgTo = new SysMsgTo();
        sysMsgTo.setMsgId(confirmMessageDto.getMsgId());
        sysMsgTo.setToId(confirmMessageDto.getToId());
        sysMsgTo.setConfirmed((short) 0);
        sysMsgTo.setConfirmTime(LocalDateTime.now());
        sysMsgToMapper.updateById(sysMsgTo);
        sysMsgFromMapper.updateReceiveCount(confirmMessageDto.getMsgId());
    }

    @Override
    @Transactional
    public void confirmMessageByType(Long userId, String type) {
        //查出这些消息
        SysMessageService proxy = (SysMessageService) AopContext.currentProxy();
        List<MessageVo> messageVoList = proxy.listMessage(userId, type);
        //提取msgId
        List<Long> msgIdList = messageVoList.stream().map(MessageVo::getId).collect(Collectors.toList());
        //更新to表
        SysMsgTo sysMsgTo = new SysMsgTo();
        LambdaUpdateWrapper<SysMsgTo> updateWrapper1 = new LambdaUpdateWrapper<>();
        updateWrapper1.in(SysMsgTo::getMsgId, msgIdList);
        updateWrapper1.eq(SysMsgTo::getToId, userId);
        updateWrapper1.set(SysMsgTo::getConfirmed, (short)0);
        updateWrapper1.set(SysMsgTo::getConfirmTime, LocalDateTime.now());
        sysMsgToMapper.update(sysMsgTo, updateWrapper1);
        //更新from表
        sysMsgFromMapper.updateReceiveCountBatch(msgIdList);
    }

    @Override
    public PageApiResult<SysMsgFrom> page(PageMessageDto pageMessageDto) {
        pageMessageDto.setPageNum(pageMessageDto.getPageNum() < 1L ? 1L : pageMessageDto.getPageNum());
        pageMessageDto.setPageSize(pageMessageDto.getPageSize() < 1L ? 50L : pageMessageDto.getPageSize());
        Page<SysMsgFrom> page = new Page<>(pageMessageDto.getPageNum(), pageMessageDto.getPageSize());
        List<SysMsgFrom> sysMsgFromList = sysMsgFromMapper.page(page, pageMessageDto);
        page.setRecords(sysMsgFromList);
        return PageApiResult
                .<SysMsgFrom>builder()
                .pageNum(page.getCurrent())
                .pageSize(page.getSize())
                .list(page.getRecords())
                .total(page.getTotal())
                .build();
    }

    @Override
    public SysMsgFrom getMessageById(Long id) {
        SysMsgFrom sysMsgFrom = sysMsgFromMapper.selectById(id);
        return sysMsgFrom;
    }

    @Override
    public List<MessageVo> listMessage(Long userId, String type) {
        if (userId == null) {
            throw new BusinessException("用户Id不能为空");
        }
        return sysMsgFromMapper.list(userId, type);
    }

    @Override
    public Integer countUnConfirmedMessage(Long userId, String type) {
        if (userId == null) {
            throw new BusinessException("用户Id不能为空");
        }

        return sysMsgFromMapper.countUnConfirmed(userId, type);
    }


    private String standardContent(String content, Long templateId) {
        if (templateId == null) {
            return content;
        }
        SysMsgTemplate template = Optional.of(sysMessageTemplateService.getTemplateById(templateId))
                .orElseThrow(() -> new BusinessException("模板不存在"));
        template.toKeywords();
        String[] keywords = template.getKeywords();
        String templateContent = template.getTemplate();
        try {
            Map<String, String> map = JSON.parseObject(content, new TypeReference<>() {
            });
            for (String keyword : keywords) {
                String value = map.get(keyword);
                System.out.println(value);
                templateContent = templateContent.replace("${" + keyword + "}", value);
            }
            return templateContent;
        } catch (JSONException e) {
            throw new BusinessException("消息体参数格式不正确");
        }

    }
}
